/*
 * Copyright 2011 Clean GWT
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 * in compliance with the License. You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software distributed under the License
 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
 * or implied. See the License for the specific language governing permissions and limitations under
 * the License.
 */
package com.cleangwt.user.client.activity;

import com.google.gwt.event.logical.shared.SelectionEvent;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.LazyPanel;
import com.google.gwt.user.client.ui.Widget;

/**
 * The {@link Activity} manager for managing view with lazy initialization.
 * 
 * @author Jess
 * @version 1.0
 * @since 1.0
 */
public class ActivityManager extends Composite {

  private static Widget unwrapLazyPanel(Widget w) {
    if (w instanceof LazyPanel) {
      LazyPanel lazy = (LazyPanel) w;
      lazy.ensureWidget();
      return lazy.getWidget();
    }
    return w;
  }

  private final DeckDisplay display;
  private int relatedIndex = -1;

  /**
   * Creates a activity manager with the given {@link DeckDisplay}.
   * 
   * @param deckDisplay the deck display
   */
  public ActivityManager(final DeckDisplay deckDisplay) {
    this.display = deckDisplay;
  }

  /**
   * Creates a activity manager with the given {@link TabDisplay}.
   * 
   * @param tabDisplay the tab display
   */
  public ActivityManager(final TabDisplay tabDisplay) {
    this.display = tabDisplay;
    tabDisplay.addSelectionHandler(new SelectionHandler<Integer>() {

      @Override
      public void onSelection(SelectionEvent<Integer> event) {
        setActive(event.getSelectedItem());
      }
    });
  }

  /**
   * Gets the index of visible activity.
   * 
   * @return the index of visible activity.
   */
  public int getActive() {
    return display.getVisibleDeck();
  }

  /**
   * Gets the activity of index.
   * 
   * @param index the index
   * @return the activity of index
   */
  @SuppressWarnings("unchecked")
  public <T extends Widget> T getActivity(int index) {
    return ((T) unwrapLazyPanel(display.getDeck(index)));
  }

  /**
   * Gets the display.
   * 
   * @return the display
   */
  public DeckDisplay getDisplay() {
    return display;
  }

  /**
   * Makes an activity of index to be active.
   * 
   * @param index the index
   */
  public void setActive(int index) {
    if (relatedIndex == index) {
      return;
    }
    // inactivate related activity
    if (relatedIndex != -1) {
      Widget w = unwrapLazyPanel(display.getDeck(relatedIndex));
      if (w instanceof Activity) {
        // on inactive
        ((Activity) w).onInactive();
      }
    }
    // set visible deck without firing events
    display.setVisibleDeck(index);

    if (index != -1) {
      Widget w = unwrapLazyPanel(display.getDeck(index));
      // lazy initialize
      if (w instanceof Activity) {
        if (w instanceof ForwardableActivity) {
          ((ForwardableActivity) w).setActivityManager(this);
        }
        // on active
        ((Activity) w).onActive(relatedIndex);
      }
    }
    relatedIndex = index;

  }
}
